package com.zxl.yjb.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.os.Environment;
import android.util.Base64;
import android.widget.Toast;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * Created by Administrator on 2017/4/25.
 */
public class BitmapUtil {

    public static Bitmap createThembnail(byte[] data, int offset, int length, int width, int height) {

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;

        BitmapFactory.decodeByteArray(data, offset, length, options);

        int orignalWidth = options.outWidth;
        int orignalHeight = options.outHeight;

        int ratioWidth = orignalWidth / width;

        /*int ratioHeight = orignalHeight / height;

        options.inSampleSize = ratioWidth > ratioHeight ? ratioWidth
                : ratioHeight;*/
        options.inSampleSize=ratioWidth;


        options.inPreferredConfig = Bitmap.Config.RGB_565;
        options.inJustDecodeBounds = false;


        return BitmapFactory.decodeByteArray(data, offset, length, options);
    }

    public static Bitmap createThembnail(String filePath, int width, int height){
        //options它是一个图片采样的参数
        BitmapFactory.Options options=new BitmapFactory.Options();

        //只采样边界防止第一次采样的时内存溢出out of memory
        options.inJustDecodeBounds=true;

        //进行第一次采样，只采样边界
        BitmapFactory.decodeFile(filePath,options);


        //Volley
        //获取第一次采样的结果
        int originalWidth=options.outWidth;
        int originalHeight=options.outHeight;

        //计算比例值
        int ratioWidth=originalWidth/width;
        int ratioHeight=0;
        if(height!=0){
            ratioHeight=originalHeight/height;
        }

        //为第二次采样设置比例值
        //这个值会就近就大的去寻找2的整数次幂
        options.inSampleSize=ratioWidth>ratioHeight?ratioWidth:ratioHeight;
        options.inSampleSize=ratioWidth;
        //不止采样边界
        options.inJustDecodeBounds=false;
        //还要设置像素点的格式
        options.inPreferredConfig= Bitmap.Config.RGB_565;


        //把第二次采样的结果返回
        return BitmapFactory.decodeFile(filePath,options);
    }

    /**
     * 对图片进行过压缩并保存
     *
     * @return
     */
 /*   public static String bitmapCompress(String imgPath, Context context) {

        Bitmap bitmap = BitmapFactory.decodeFile(imgPath);
        //将压缩后的图片,重新保存
        String sdState = Environment.getExternalStorageState();
        if (!sdState.equals(Environment.MEDIA_MOUNTED)) {
            Toast.makeText(context, "SDCard未挂载", Toast.LENGTH_SHORT).show();
            return imgPath;
        }
        File appDir = new File(Environment.getExternalStorageDirectory(), "Boohee11");
        if (!appDir.exists()) {
            appDir.mkdir();
        }
        String fileName = System.currentTimeMillis() + ".jpg";
        File file = new File(appDir, fileName);
        int options_ = 100;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, options_, baos);//这里100表示不压缩，将不压缩的数据存放到baos中
        while (baos.toByteArray().length / 1024 > 256) {//如果图片大于就进行压缩(二次采样 压缩大小)
            int length = baos.toByteArray().length;
            int i = baos.toByteArray().length / 1024;
            byte[] bytes = baos.toByteArray();
            baos.reset();
            options_ = Math.max(0, options_ - 30);//图片质量每次减少10
//            bitmap = createThembnail(bytes, 0, bytes.length, 640, 0);
            bitmap.compress(Bitmap.CompressFormat.JPEG, options_, baos);
            if (options_ == 0)//如果图片的质量已降到最低则，不再进行压缩
                break;
        }
        //回收图片，清理内存
        if (bitmap != null && !bitmap.isRecycled()) {
            bitmap.recycle();
            bitmap = null;
            System.gc();
        }
        //将输出流写入到新文件
        try {
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(baos.toByteArray());
            fos.flush();
            fos.close();
            baos.close();
            //标记压缩图片成功
        } catch (Exception e) {
            e.printStackTrace();
        }
        return file.getAbsolutePath();
    }*/
    /*//进行有损压缩
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int options_ = 100;
actualOutBitmap.compress(Bitmap.CompressFormat.JPEG, options_, baos);//质量压缩方法，把压缩后的数据存放到baos中 (100表示不压缩，0表示压缩到最小)

int baosLength = baos.toByteArray().length;
while (baosLength / 1024 > maxFileSize) {//循环判断如果压缩后图片是否大于maxMemmorrySize,大于继续压缩
    baos.reset();//重置baos即让下一次的写入覆盖之前的内容
    options_ = Math.max(0, options_ - 10);//图片质量每次减少10
    actualOutBitmap.compress(Bitmap.CompressFormat.JPEG, options_, baos);//将压缩后的图片保存到baos中
    baosLength = baos.toByteArray().length;
    if (options_ == 0)//如果图片的质量已降到最低则，不再进行压缩
        break;

*/

    // 将图片转换成base64编码
    public static String getBase64(Bitmap bitmap) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        //压缩的质量为60%
        bitmap.compress(Bitmap.CompressFormat.PNG, 60, out);
        //生成base64字符
        String base = Base64.encodeToString(out.toByteArray(), Base64.DEFAULT);
        return base;
    }

    public static void compressBitmapToFile(Bitmap bmp, File file){
        // 尺寸压缩倍数,值越大，图片尺寸越小
        int ratio = 2;
        // 压缩Bitmap到对应尺寸
        Bitmap result = Bitmap.createBitmap(bmp.getWidth() / ratio, bmp.getHeight() / ratio, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(result);
        Rect rect = new Rect(0, 0, bmp.getWidth() / ratio, bmp.getHeight() / ratio);
        canvas.drawBitmap(bmp, null, rect, null);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        // 把压缩后的数据存放到baos中
        result.compress(Bitmap.CompressFormat.JPEG, 100 ,baos);
        try {
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(baos.toByteArray());
            fos.flush();
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }



    public static String bitmapCompress(String imgPath, Context context) {
//将压缩后的图片,重新保存
        String sdState = Environment.getExternalStorageState();
        if (!sdState.equals(Environment.MEDIA_MOUNTED)) {
            Toast.makeText(context, "SDCard未挂载", Toast.LENGTH_SHORT).show();
            return imgPath;
        }
        File appDir = new File(Environment.getExternalStorageDirectory(), "Boohee11");
        if (!appDir.exists()) {
            appDir.mkdir();
        }
        String fileName = System.currentTimeMillis() + ".jpg";
        File file = new File(appDir, fileName);
        if (file != null && !file.exists())
        {
            try {
                file.createNewFile();
            } catch (Exception e) {

            }
        }
        File imageFile = new File(imgPath);

//        Bitmap bitmap = BitmapFactory.decodeFile(imgPath);
        BitmapFactory.Options bfOptions=new BitmapFactory.Options();
        bfOptions.inDither=false;
        bfOptions.inPurgeable=true;
        bfOptions.inTempStorage=new byte[12 * 1024];
        bfOptions.inJustDecodeBounds = false;
        FileInputStream fs=null;
        Bitmap bitmap = null;
        try {
            fs = new FileInputStream(imageFile);
            if(fs != null)
                bitmap = BitmapFactory.decodeFileDescriptor(fs.getFD(), null, bfOptions);
        } catch (Exception e) {
            e.printStackTrace();
        }

//根据原始图片的宽高比和期望的输出图片的宽高比计算最终输出的图片的宽和高
        float srcWidth = bitmap.getWidth();
        float srcHeight = bitmap.getHeight();
        float srcRatio = srcWidth / srcHeight;
        float maxWidth = 720;//期望输出的图片宽度
        float  maxHeight = maxWidth/srcRatio;//期望输出的图片高度
        float actualOutWidth = srcWidth;//最终输出的图片宽度
        float actualOutHeight = srcHeight;//最终输出的图片高度

        if (srcWidth > maxWidth || srcHeight > maxHeight) {

                actualOutWidth = maxWidth;
                actualOutHeight = maxHeight;
        }else {
            return imgPath;
        }

        // 压缩Bitmap到对应尺寸
        Bitmap result = Bitmap.createBitmap((int)actualOutWidth,(int)actualOutHeight, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(result);
        Rect rect = new Rect(0, 0, (int)actualOutWidth, (int)actualOutHeight);
        canvas.drawBitmap(bitmap, null, rect, null);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        // 把压缩后的数据存放到baos中
        result.compress(Bitmap.CompressFormat.JPEG, 100 ,baos);

        //将输出流写入到新文件
        try {
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(baos.toByteArray());
            fos.flush();
            fos.close();
            baos.close();
            //标记压缩图片成功
        } catch (Exception e) {
            e.printStackTrace();
        }
        //回收图片，清理内存
        if (bitmap != null && !bitmap.isRecycled()) {
            bitmap.recycle();
            bitmap = null;
            System.gc();
        }
        return file.getAbsolutePath();
    }




    public static void compressBitmap(String filePath, File file){
        // 数值越高，图片像素越低
        int inSampleSize = 2;
        BitmapFactory.Options options = new BitmapFactory.Options();
        //采样率
        options.inSampleSize = inSampleSize;
        Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        // 把压缩后的数据存放到baos中
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100 ,baos);
        try {
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(baos.toByteArray());
            fos.flush();
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }



    public static String decodeBitmap(String path, Context context) {

        String sdState = Environment.getExternalStorageState();
        if (!sdState.equals(Environment.MEDIA_MOUNTED)) {
            Toast.makeText(context, "SDCard未挂载", Toast.LENGTH_SHORT).show();
            return path;
        }
        File appDir = new File(Environment.getExternalStorageDirectory(), "Boohee11");
        if (!appDir.exists()) {
            appDir.mkdir();
        }
        String fileName = System.currentTimeMillis() + ".jpg";
        File file = new File(appDir, fileName);
        if (file != null && !file.exists())
        {
            try {
                file.createNewFile();
            } catch (Exception e) {

            }
        }

        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inJustDecodeBounds = true;// 设置成了true,不占用内存，只获取bitmap宽高
        BitmapFactory.decodeFile(path, opts);
        opts.inSampleSize = computeSampleSize(opts, -1, 1024 * 800);
        opts.inJustDecodeBounds = false;// 这里一定要将其设置回false，因为之前我们将其设置成了true
        opts.inPurgeable = true;
        opts.inInputShareable = true;
        opts.inDither = false;
        opts.inPurgeable = true;
        opts.inTempStorage = new byte[16 * 1024];
        FileInputStream is = null;
        Bitmap bmp = null;
//        InputStream ins = null;
        ByteArrayOutputStream baos = null;
        try {
            is = new FileInputStream(path);
            bmp = BitmapFactory.decodeFileDescriptor(is.getFD(), null, opts);
            double scale = getScaling(opts.outWidth * opts.outHeight, 1024 * 600);
            Bitmap bmp2 = Bitmap.createScaledBitmap(bmp,
                    (int) (opts.outWidth * scale),
                    (int) (opts.outHeight * scale), true);
            bmp.recycle();
            baos = new ByteArrayOutputStream();
            bmp2.compress(Bitmap.CompressFormat.JPEG, 100, baos);
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(baos.toByteArray());
            fos.flush();
            fos.close();
            bmp2.recycle();
            return file.getAbsolutePath();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
//                ins.close();
                baos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            System.gc();
        }
        return file.getAbsolutePath();
    }

    private static double getScaling(int src, int des) {
/**
 * 目标尺寸÷原尺寸 sqrt开方，得出宽高百分比
 */
        double scale = Math.sqrt((double) des / (double) src);
        return scale;
    }


    public static int computeSampleSize(BitmapFactory.Options options,
                                        int minSideLength, int maxNumOfPixels) {
        int initialSize = computeInitialSampleSize(options, minSideLength,
                maxNumOfPixels);

        int roundedSize;
        if (initialSize <= 8) {
            roundedSize = 1;
            while (roundedSize < initialSize) {
                roundedSize <<= 1;
            }
        } else {
            roundedSize = (initialSize + 7) / 8 * 8;
        }

        return roundedSize;
    }

    private static int computeInitialSampleSize(BitmapFactory.Options options,
                                                int minSideLength, int maxNumOfPixels) {
        double w = options.outWidth;
        double h = options.outHeight;

        int lowerBound = (maxNumOfPixels == -1) ? 1 :
                (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
        int upperBound = (minSideLength == -1) ? 128 :
                (int) Math.min(Math.floor(w / minSideLength),
                        Math.floor(h / minSideLength));

        if (upperBound < lowerBound) {
            return lowerBound;
        }

        if ((maxNumOfPixels == -1) &&
                (minSideLength == -1)) {
            return 1;
        } else if (minSideLength == -1) {
            return lowerBound;
        } else {
            return upperBound;
        }
    }

}
